/**
 * A wrapper class around the XmlHttpRequest object.
 * @param {lib.net.Method} method The request method.
 * @param {String} url The request url.
 * @constructor
 * @extends {lib.event.EventTarget}
 */
lib.net.Xhr = function(method, url) {
	lib.event.EventTarget.call(this);

	this.xhr_ = new XMLHttpRequest();
	this.method_ = method;
	this.url_ = url;
};
lib.inherits(lib.net.Xhr, lib.event.EventTarget);

/**
 * Sends an asynchronous request.
 * @param {Object} params Request parameters in key/value pairs to send.
 */
lib.net.Xhr.prototype.send = function(params) {
	var readyState = this.xhr_.readyState;
	if (readyState == lib.net.ReadyState.UNSENT || readyState == lib.net.ReadyState.DONE) {
		this.xhr_.open(this.method_, this.url_, true);
		this.xhr_.onreadystatechange = this.onReadyStateChange.bind(this);

		if (this.method_ == lib.net.Method.POST) {
			this.xhr_.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		}


		var paramArr = [];
		for (var i in params) {
			var param = params[i];
			if (param.push) {
				for (var j=0, len=param.length; j<len; j++) {
					paramArr.push(i + '[' + j + ']=' + encodeURIComponent(param[j]));
				}
			} else {
				paramArr.push(i + '=' + encodeURIComponent(param));
			}
		}
		
		this.xhr_.send(paramArr.join('&'));
	}
};

/**
 * Handles the XHR's onreadystatechange event.
 * @private
 */
lib.net.Xhr.prototype.onReadyStateChange = function() {
	if (this.xhr_.readyState == lib.net.ReadyState.DONE) {
		if (this.xhr_.status == lib.net.Status.OK) {
			var response = this.xhr_.responseText;
			var obj = null;
			try {
				obj = eval('(' + response + ')');
			} catch(e) {}
			
			if (obj) {
				this.trigger_(lib.net.Xhr.Event.COMPLETE, obj);
			} else {
				this.trigger_(lib.net.Xhr.Event.ERROR, lib.net.Error.EVAL, response);
			}
		} else {
			this.trigger_(lib.net.Xhr.Event.ERROR, lib.net.Error.STATUS, this.xhr_.status);
		}
	}
};

/**
 * @name Event enumeration for the Xhr class.
 */
lib.net.Xhr.Event = {
	COMPLETE: 'complete',
	ERROR: 'error'
};
